package com.smart.community.parking.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smart.community.commons.result.PageResult;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.parking.dto.ParkingLotDTO;
import com.smart.community.parking.dto.ParkingLotQueryDTO;
import com.smart.community.parking.entity.ParkingLot;
import com.smart.community.parking.entity.ParkingSpace;
import com.smart.community.parking.mapper.ParkingLotMapper;
import com.smart.community.parking.mapper.ParkingSpaceMapper;
import com.smart.community.parking.service.IParkingLotService;
import com.smart.community.parking.vo.ParkingLotStatusVO;
import com.smart.community.parking.vo.ParkingLotVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 停车场服务实现类
 * 
 * @author Wu.Liang
 * @since 2024-12-21
 */
@Slf4j
@Service
public class ParkingLotServiceImpl implements IParkingLotService {

    @Autowired
    private ParkingLotMapper parkingLotMapper;

    @Autowired
    private ParkingSpaceMapper parkingSpaceMapper;

    @Override
    public PageResult<ParkingLotVO> getParkingLotList(ParkingLotQueryDTO queryDTO, Long userId) {
        // 构建查询条件
        LambdaQueryWrapper<ParkingLot> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(queryDTO.getLotName()), ParkingLot::getLotName, queryDTO.getLotName())
               .like(StringUtils.hasText(queryDTO.getLotCode()), ParkingLot::getLotCode, queryDTO.getLotCode())
               .eq(queryDTO.getCommunityId() != null, ParkingLot::getCommunityId, queryDTO.getCommunityId())
               .eq(queryDTO.getStatus() != null, ParkingLot::getStatus, queryDTO.getStatus())
               .orderByDesc(ParkingLot::getCreateTime);

        // 分页查询
        Page<ParkingLot> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        IPage<ParkingLot> lotPage = parkingLotMapper.selectPage(page, wrapper);

        // 转换为VO
        List<ParkingLotVO> voList = lotPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>((int) lotPage.getCurrent(), (int) lotPage.getSize(), lotPage.getTotal(), voList);
    }

    @Override
    public ParkingLotVO getParkingLot(Long id, Long userId) {
        ParkingLot parkingLot = parkingLotMapper.selectById(id);
        if (parkingLot == null) {
            return null;
        }
        return convertToVO(parkingLot);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createParkingLot(ParkingLotDTO parkingLotDTO, Long userId) {
        // 验证停车场编码是否存在
        ParkingLot existLot = parkingLotMapper.selectByLotCode(parkingLotDTO.getLotCode());
        if (existLot != null) {
            throw new RuntimeException("停车场编码已存在");
        }

        // 创建停车场
        ParkingLot parkingLot = new ParkingLot();
        BeanUtils.copyProperties(parkingLotDTO, parkingLot);
        parkingLot.setAvailableSpaces(parkingLotDTO.getTotalSpaces());
        parkingLot.setCreateTime(LocalDateTime.now());

        int result = parkingLotMapper.insert(parkingLot);
        if (result <= 0) {
            return false;
        }

        // 创建车位
        createParkingSpaces(parkingLot.getId(), parkingLotDTO.getTotalSpaces());

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateParkingLot(Long id, ParkingLotDTO parkingLotDTO, Long userId) {
        ParkingLot existLot = parkingLotMapper.selectById(id);
        if (existLot == null) {
            throw new RuntimeException("停车场不存在");
        }

        // 检查编码是否重复
        ParkingLot codeExistLot = parkingLotMapper.selectByLotCode(parkingLotDTO.getLotCode());
        if (codeExistLot != null && !codeExistLot.getId().equals(id)) {
            throw new RuntimeException("停车场编码已存在");
        }

        // 更新停车场
        ParkingLot parkingLot = new ParkingLot();
        BeanUtils.copyProperties(parkingLotDTO, parkingLot);
        parkingLot.setId(id);

        int result = parkingLotMapper.updateById(parkingLot);
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteParkingLot(Long id, Long userId) {
        ParkingLot parkingLot = parkingLotMapper.selectById(id);
        if (parkingLot == null) {
            throw new RuntimeException("停车场不存在");
        }

        // 检查是否有停车记录
        // TODO: 这里需要检查停车记录表

        int result = parkingLotMapper.deleteById(id);
        return result > 0;
    }

    @Override
    public ParkingLotStatusVO getParkingLotStatus(Long id, Long userId) {
        ParkingLot parkingLot = parkingLotMapper.selectById(id);
        if (parkingLot == null) {
            return null;
        }

        ParkingLotStatusVO statusVO = new ParkingLotStatusVO();
        statusVO.setId(parkingLot.getId());
        statusVO.setLotName(parkingLot.getLotName());
        statusVO.setTotalSpaces(parkingLot.getTotalSpaces());
        statusVO.setAvailableSpaces(parkingLot.getAvailableSpaces());
        statusVO.setOccupiedSpaces(parkingLot.getTotalSpaces() - parkingLot.getAvailableSpaces());
        statusVO.setStatus(parkingLot.getStatus());
        statusVO.setStatusName(parkingLot.getStatus() == 1 ? "开放" : "关闭");

        // 计算占用率
        if (parkingLot.getTotalSpaces() > 0) {
            BigDecimal occupancyRate = BigDecimal.valueOf(parkingLot.getTotalSpaces() - parkingLot.getAvailableSpaces())
                    .divide(BigDecimal.valueOf(parkingLot.getTotalSpaces()), 4, RoundingMode.HALF_UP)
                    .multiply(BigDecimal.valueOf(100));
            statusVO.setOccupancyRate(occupancyRate);
        } else {
            statusVO.setOccupancyRate(BigDecimal.ZERO);
        }

        return statusVO;
    }

    /**
     * 转换为VO
     */
    private ParkingLotVO convertToVO(ParkingLot parkingLot) {
        ParkingLotVO vo = new ParkingLotVO();
        BeanUtils.copyProperties(parkingLot, vo);
        vo.setOccupiedSpaces(parkingLot.getTotalSpaces() - parkingLot.getAvailableSpaces());
        vo.setStatusName(parkingLot.getStatus() == 1 ? "开放" : "关闭");
        return vo;
    }

    /**
     * 创建车位
     */
    private void createParkingSpaces(Long lotId, Integer totalSpaces) {
        List<ParkingSpace> spaces = new ArrayList<>();
        for (int i = 1; i <= totalSpaces; i++) {
            ParkingSpace space = new ParkingSpace();
            space.setSpaceNo(String.format("A%03d", i));
            space.setLotId(lotId);
            space.setSpaceType(1); // 普通车位
            space.setStatus(1);    // 空闲
            space.setCreateTime(LocalDateTime.now());
            spaces.add(space);
        }
        
        // 批量插入车位
        parkingSpaceMapper.batchInsert(spaces);
    }
} 